﻿Imports System.Data.SqlClient
Imports System.Web.Configuration

Namespace Account
    Public Class Activate
        Inherits System.Web.UI.Page

#Region " Database variables "

        ''' <summary>
        ''' Set the database connection variables used throughout this class.
        ''' </summary>
        ''' <remarks>Placed here so they will not need to be typed out each time they are needed.</remarks>
        Private connectionString As String = WebConfigurationManager.ConnectionStrings("SqlConnectionString").ConnectionString()
        Private connection As SqlConnection = New SqlConnection(connectionString)
        Private command As New SqlCommand

#End Region

#Region " Page events "

        ''' <summary>
        ''' Handles the Load event of the Page control.
        ''' </summary>
        ''' <param name="sender">The source of the event.</param>
        ''' <param name="e">The <see cref="System.EventArgs" /> instance containing the event data.</param>
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            ' Populate the email address field with the users email address supplied in the query string if available.
            If Not Request.QueryString("email") Is Nothing Then
                txtEmail.Text = Request.QueryString("email")
            End If

            ' Populate the activation code field with the code supplied in the query string if available.
            If Not Request.QueryString("code") Is Nothing Then
                txtCode.Text = Request.QueryString("code")
            End If

            ' Make sure that the form panel is shown and complete panel is hidden.
            panForm.Visible = True
            panInstructions.Visible = False
        End Sub

#End Region

#Region " Click event for when the activation form is submitted. "

        ''' <summary>
        ''' Handles the Click event of the btnActivate control.
        ''' </summary>
        ''' <param name="sender">The source of the event.</param>
        ''' <param name="e">The <see cref="System.EventArgs" /> instance containing the event data.</param>
        Protected Sub btnActivate_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnActivate.Click
            If Page.IsValid Then
                Try
                    ' If the supplied information is valid mark account as active and change activation code.
                    command = New SqlCommand("sp_public_activateAccount", connection)
                    command.CommandType = CommandType.StoredProcedure
                    command.Parameters.Add("@Email", SqlDbType.NVarChar, 100)
                    command.Parameters("@Email").Value = txtEmail.Text
                    command.Parameters.Add("@Active", SqlDbType.Bit)
                    command.Parameters("@Active").Value = True
                    command.Parameters.Add("@Code", SqlDbType.NChar, 10)
                    command.Parameters("@Code").Value = MakeActivationCode(10)
                    connection.Open()
                    command.ExecuteNonQuery()
                    connection.Close()

                    ' Hide the activation panel from the visitor and display activation complete panel.
                    panForm.Visible = False
                    panInstructions.Visible = True
                Catch ex As Exception

                End Try
            End If
        End Sub

#End Region

#Region " Form OnServerValidate functions. "

        ''' <summary>
        ''' Handles the ServerValidate event of the valEmail control.
        ''' </summary>
        ''' <param name="source">The source of the event.</param>
        ''' <param name="args">The <see cref="System.Web.UI.WebControls.ServerValidateEventArgs" /> instance containing the event data.</param>
        Protected Sub valEmail_ServerValidate(ByVal source As Object, ByVal args As ServerValidateEventArgs)
            ' Check that a vaild email was entered.
            args.IsValid = True

            ' Check that the email field has any content.
            If txtEmail.Text = Nothing Then
                valEmail.ErrorMessage = "This field is required."
                args.IsValid = False
            End If

            ' Check the length of the email address supplied is no more then 100 charaters.
            If txtEmail.Text.Length > 100 Then
                valEmail.ErrorMessage = "Please enter no more then 100 charaters."
                args.IsValid = False
            End If

            ' Make sure what appears to be a valid email address has been supplied.
            Dim emailRegex As New Regex("^([0-9a-zA-Z]([-\.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$")
            If emailRegex.IsMatch(txtEmail.Text) = False Then
                valEmail.ErrorMessage = "Please enter a valid email address."
                args.IsValid = False
            End If
        End Sub

        ''' <summary>
        ''' Handles the ServerValidate event of the valCode control.
        ''' </summary>
        ''' <param name="source">The source of the event.</param>
        ''' <param name="args">The <see cref="System.Web.UI.WebControls.ServerValidateEventArgs" /> instance containing the event data.</param>
        Protected Sub valCode_ServerValidate(ByVal source As Object, ByVal args As ServerValidateEventArgs)
            ' Check that a possible vaild code was entered.
            args.IsValid = True

            ' Check that the code field has any content.
            If txtCode.Text = Nothing Then
                valCode.ErrorMessage = "This field is required."
                args.IsValid = False
            End If

            ' Check that the length of the activation code supplied is at least 10 charaters.
            If txtCode.Text.Length() < 10 Then
                valCode.ErrorMessage = "Please enter at least 10 characters."
                args.IsValid = False
            End If

            ' Check that the length of the activation code supplied is no more then 10 characters.
            If txtCode.Text.Length() > 10 Then
                valCode.ErrorMessage = "Please enter no more then 10 charaters."
                args.IsValid = False
            End If

            ' Check that the supplied activation code is alphanumeric only.
            Dim loginRegex As New Regex("[a-zA-Z0-9]")
            If txtCode.Text = "" Or loginRegex.IsMatch(txtCode.Text) = False Then
                valCode.ErrorMessage = "Please enter a valid code."
                args.IsValid = False
            End If

            ' Check that code matches the supplied email address in the system.
            Try
                command = New SqlCommand("sp_public_checkCode", connection)
                command.CommandType = CommandType.StoredProcedure
                command.Parameters.Add("@Email", SqlDbType.NVarChar, 100)
                command.Parameters("@Email").Value = txtEmail.Text.ToLower
                command.Parameters.Add("@Code", SqlDbType.NChar, 10)
                command.Parameters("@Code").Value = txtCode.Text.ToUpper
                command.Parameters.Add("@Total", SqlDbType.Int)
                command.Parameters("@Total").Direction = ParameterDirection.Output
                connection.Open()
                command.ExecuteNonQuery()
                Dim totalMatches As Integer = CInt(command.Parameters("@Total").Value)
                If totalMatches = 0 Then
                    valCode.ErrorMessage = "Invalid code supplied or account already activated."
                    args.IsValid = False
                End If
                connection.Close()
            Catch ex As Exception
                ' Any exception will cause args.IsValid to equal False.
                valCode.ErrorMessage = "There was an error processing this field."
                args.IsValid = False
            End Try

        End Sub

#End Region

#Region " Data generation specific functions. "

        ''' <summary>
        ''' Generates a random activation code.
        ''' </summary>
        ''' <param name="size">The length we want the string to be.</param>
        ''' <returns>Returns the randomly generated activation code user to activate the new account.</returns>
        Private Function MakeActivationCode(ByVal size As Integer) As String
            Dim rand As New Random()
            ' Characters we will use to generate this random string.
            Dim allowableChars() As Char = "ABCDEFGHIJKLOMNOPQRSTUVWXYZ0123456789".ToCharArray()

            ' Start generating the random string.
            Dim activationCode As String = String.Empty
            For i As Integer = 0 To size - 1
                activationCode += allowableChars(rand.Next(allowableChars.Length - 1))
            Next

            ' Return the random string in upper case.
            Return activationCode.ToUpper()
        End Function

#End Region

    End Class
End Namespace